/* 
*  Copyright (C) 2009-2010 WCG Project
*
*  This program is free software; you can redistribute it and/or modify it
*  under the terms of the GNU General Public License as published by the
*  Free Software Foundation; either version 2 of the License, or (at
*  your option) any later version.
*
*  This program is distributed in the hope that it will be useful, but
*  WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
*  General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software Foundation,
*  Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*  In addition, as a special exception, the author gives permission to
*  link the code of this program with the Half-Life Game Engine ("HL
*  Engine") and Modified Game Libraries ("MODs") developed by Valve,
*  L.L.C ("Valve"). You must obey the GNU General Public License in all
*  respects for all of the code used other than the HL Engine and MODs
*  from Valve. If you modify this file, you may extend this exception
*  to your version of the file, but you are not obligated to do so. If
*  you do not wish to do so, delete this exception statement from your
*  version.
*/



#define IMMOLATE_DAMAGE			35		// Initial damage done to target players
#define IMMOLATE_DOT_DAMAGE		5		// Damage done on each tick of the ultimate
#define IMMOLATE_DOT			7		// Number of times ultimate ticks

#define WARLOCK_PHOENIX_RANGE		750		// Range to award money
#define BANISH_DAMAGE			10
#define BANISH_HOLDTIME			0.7


new const Float:p_banish[5]				= {0.02, 0.04, 0.06, 0.08, 0.10}		// Banish
new const Float:p_mana[5]				= {0.01, 0.02, 0.03, 0.04, 0.05}		// Siphon Mana
new const Float:p_imp_mana[5]			= {0.20, 0.40, 0.60, 0.80, 1.00}		// Improved Siphon Mana
new const p_siphon_manacost[5]			= { 2, 4, 6, 8, 10 }
new const Float:p_demonarmor[5]			= {0.03, 0.06, 0.09, 0.12, 0.15}
new const Float:p_soulstone[5]			= {0.4, 0.5, 0.6, 0.7, 0.8}				// Soulstone



WARLOCK_InitSkills()
{
	SM_InitSkill( SKILL_BANISH, CLASS_WARLOCK, SKILL_TYPE_TRAINABLE, sizeof(p_banish), 1, 5 )
	SM_InitSkill( SKILL_SIPHONMANA, CLASS_WARLOCK, SKILL_TYPE_TRAINABLE, sizeof(p_mana) )
	SM_InitSkill( SKILL_IMPROVEDSIPHONMANA, CLASS_WARLOCK, SKILL_TYPE_TRAINABLE, sizeof(p_imp_mana), 10, _, SKILL_SIPHONMANA )
	SM_InitSkill( SKILL_SOULSTONE, CLASS_WARLOCK, SKILL_TYPE_TRAINABLE, 5, 15, 999 )
	SM_InitSkill( SKILL_DEMONARMOR, CLASS_WARLOCK, SKILL_TYPE_TRAINABLE, sizeof(p_demonarmor) )
	SM_InitSkill( ULTIMATE_IMMOLATE, CLASS_WARLOCK, SKILL_TYPE_ULTIMATE, 1, 10, 10 )
}





/*
//------------------------------------
// WARLOCK_TriggerAbility
//
//------------------------------------
WARLOCK_TriggerAbility( id, iSkillID )
{

}
*/



//------------------------------------
// WARLOCK_TriggerUltimate
//
//------------------------------------
WARLOCK_TriggerUltimate( id, iSkillID )
{
	if( iSkillID == ULTIMATE_IMMOLATE )
	{
		PLAYER_CastSpell( id, ULTIMATE_IMMOLATE, CAST_SEARCH, "_SPELL_Immolate", _, _, CAST_SEARCH_OPPOSITE_TEAM )
	}
}





//------------------------------------
// WARLOCK_SkillsOffensive
//
//------------------------------------
public WARLOCK_SkillsOffensive( iAttacker, iVictim, iWeapon, &iDamage, iDamageType )
{
	static iSkillLevel

	// Siphon Mana
	iSkillLevel = SM_GetSkillLevel( iAttacker, SKILL_SIPHONMANA )
	if( iSkillLevel > 0 && (iDamageType & (DMG_BULLET|DMG_SLASH|DMG_HEGRENADE)) )
	{
		new param[3]
		param[0] = iAttacker
		param[1] = iVictim
		param[2] = iSkillLevel
		PLAYER_CastSpell( iAttacker, SKILL_SIPHONMANA, CAST_PASSIVE, "_SPELL_SiphonMana", param, 3 )
	}
}




//------------------------------------
// WARLOCK_SkillsDefensive
//
//------------------------------------
public WARLOCK_SkillsDefensive( iAttacker, iVictim, &iDamage, iWeapon, iDamageType )
{
	new iSkillLevel

	// Resistant skin
	iSkillLevel = SM_GetSkillLevel( iVictim, SKILL_DEMONARMOR )
	if( iDamage > 0 && iSkillLevel > 0 )
		iDamage -= floatround( float( iDamage ) * p_demonarmor[iSkillLevel-1] )
	
	
	iSkillLevel = SM_GetSkillLevel( iVictim, SKILL_BANISH )
	if( iSkillLevel > 0 && (iDamageType & (DMG_BULLET|DMG_SLASH)) )
	{
		if( random_float( 0.0, 1.0 ) <= p_banish[iSkillLevel-1] )
		{
			new param[2]
			param[0] = iAttacker
			param[1] = iVictim

			if( PLAYER_CastSpell( iVictim, SKILL_BANISH, CAST_PASSIVE, "_SPELL_Banish", param, 2 ) )
				iDamage = 0
		}
	}
}


//--------------------------------------------------------------------------------------------------------------------------
// Soulstone

//------------------------------------
// WARLOCK_CheckSoulstone
//
//------------------------------------
WARLOCK_CheckSoulstone( id )
{
	if( is_user_alive( id ) || SM_IsOnCooldown( id, SKILL_SOULSTONE ) )
		return

	if( PlayerInfo[id][PI_RespawnBy] || PlayerInfo[id][PI_ChangingTeam] || GameInfo[GI_EndRound] )
		return

	new iSkillLevel = SM_GetSkillLevel( id, SKILL_SOULSTONE ) 
	if( iSkillLevel <= 0 )
		return

	// We need to set that we're about to respawn
	PlayerInfo[id][PI_RespawnBy] = RESPAWN_SOULSTONE

	new param[2]
	param[0] = id
	param[1] = 10
	set_task( 1.0, "_SoulstoneRespawn", TASK_EFFECT + id, param, 2 )
}



//------------------------------------
// _SoulstoneRespawn
//
//------------------------------------
public _SoulstoneRespawn( param[] )
{
	new id			= param[0]
	new iCounter	= param[1]

	if( is_user_alive(id) || PlayerInfo[id][PI_ChangingTeam] || GameInfo[GI_EndRound] )
		return

	if( iCounter > 0 )
	{
		WCG_StatusText( id, TXT_TIMER, HUD_TIMER, "%d seconds until soulstone activation", iCounter )
		param[1] = --iCounter
		set_task( 1.0, "_SoulstoneRespawn", TASK_EFFECT + id, param, 2 )
		return
	}
	else
		WCG_StatusText( id, TXT_TIMER, HUD_TIMER, "" )

	PLAYER_Spawn( id )
}

//--------------------------------------------------------------------------------------------------------------------------
// Banish


//------------------------------------
// _SPELL_Banish
//
// PLAYER_CastSpell callback
//		param[0] = Attacker ID (player that will be banished)
//		param[1] = Victim ID (caster)
//------------------------------------
public _SPELL_Banish( const param[] )
{
	new iAttacker = param[0]
	new iVictim = param[1]

	if( !PLAYER_CheckMagicHit( iVictim, iAttacker ) )
	{
		client_print( iVictim, print_chat, "Your Banish was resisted by %s.", PlayerInfo[iAttacker][PI_PlayerName] )
		client_print( iAttacker, print_chat, "You resisted %s's Banish.", PlayerInfo[iVictim][PI_PlayerName] )
		client_cmd( iVictim, "spk %s", g_szSounds[SOUND_DISPELL] )
		return
	}

	// Deal some damage
	PLAYER_MagicDamage( iAttacker, iVictim, BANISH_DAMAGE, CSW_BANISH, DMG_FREEZE )

	// Play the Banish sound
	emit_sound( iAttacker, CHAN_STATIC, g_szSounds[SOUND_BANISH], 1.0, ATTN_NORM, 0, PITCH_NORM )

	// Black screen the user!
	EFFECT_ScreenFade( iAttacker, 1.0, 0.25, COLOR_RGBA(0, 0, 0, 255) )

	new vOrigin[3]
	get_user_origin( iAttacker, vOrigin )

	new param[4]
	param[0] = iAttacker
	param[1] = vOrigin[0]
	param[2] = vOrigin[1]
	param[3] = vOrigin[2]

	// Create the "banish" sprite
	Create_TE_SPRITE( vOrigin, g_spr_nhth1, 10, 255 )

	vOrigin[2] -= 2000

	fm_reset_user_velocity( iAttacker )

	fm_set_user_origin( iAttacker, vOrigin )

	// Black screen the user!
	EFFECT_ScreenFade( iAttacker, 1.0, 1 + BANISH_HOLDTIME, COLOR_RGBA(0, 0, 0, 255) )

	set_task( BANISH_HOLDTIME, "_SPELL_BanishReturn", TASK_EFFECT, param, 4 )
}


//------------------------------------
// _SPELL_BanishReturn
//
//------------------------------------
public _SPELL_BanishReturn( const param[4] )
{
	static vOrigin[3]
	
	new id = param[0]
	
	if ( !is_user_connected(id) )
		return

	vOrigin[0] = param[1]
	vOrigin[1] = param[2]
	vOrigin[2] = param[3]

	fm_reset_user_velocity( id )

	// Move the user back!
	SHARED_Teleport( id, vOrigin )

	// Make the user glow!
	SHARED_Glow( id, COLOR_RGB( 100, 100, 100 ) )

	// Create a screen fade
	EFFECT_ScreenFade( id, 1.0, 0.2, COLOR_RGBA(0, 0, 0, 255) )
}





//--------------------------------------------------------------------------------------------------------------------------
// Siphon Mana


//------------------------------------
// _SPELL_SiphonMana
//
// PLAYER_CastSpell callback
//		param[0] = Caster ID
//		param[1] = Victim ID
//		param[2] = SkillLevel of siphon mana to be executed
//------------------------------------
public _SPELL_SiphonMana( const param[] )
{
	new id = param[0]
	new iVictim = param[1]
	new iSkillLevel = param[2]

	if( !is_user_alive(id) || !is_user_alive( iVictim ) )
		return

	if( !PLAYER_CheckMagicHit( id, iVictim ) )
		return

	new iImpSkillLevel = SM_GetSkillLevel( id, SKILL_IMPROVEDSIPHONMANA )
	if( iImpSkillLevel > 0 )
	{
		if( random_float( 0.0, 1.0 ) <= p_imp_mana[iImpSkillLevel-1] )
			PlayerInfo[id][PI_Mana] += PlayerInfo[id][PI_LastManaCost]
	}

	new iVictimMoney = cs_get_user_money(iVictim)
	new iCasterMoney = cs_get_user_money(id)
	new iMoneyStolen = floatround( p_mana[iSkillLevel-1] * iVictimMoney )

	PlayerInfo[iVictim][PI_Mana] = max( PlayerInfo[iVictim][PI_Mana] - iSkillLevel, 0 )
	PlayerInfo[id][PI_Mana] = min( PlayerInfo[id][PI_Mana] + iSkillLevel, PlayerInfo[id][PI_MaxMana] )

	if( iMoneyStolen > 0 && iCasterMoney != 16000 )
	{
		// Remove the money from the victim
		cs_set_user_money( iVictim, iVictimMoney - iMoneyStolen, 1 )
		
		// Give the money to the attacker
		cs_set_user_money( id, min(iCasterMoney+iMoneyStolen, 16000), 1 )

		new iBrightness = min( iMoneyStolen/8, 150 )
	
		// Make the user glow!
		SHARED_Glow( iVictim, COLOR_RGB( 0, 3*iBrightness, 0 ) )
		
		// Create a screen fade (purplish)
		EFFECT_ScreenFade( id, 0.25, 0.25, COLOR_RGBA(144, 58, 255, iBrightness) )
	}
}






//--------------------------------------------------------------------------------------------------------------------------
// Immolate


//------------------------------------
// _SPELL_Immolate
//
// PLAYER_CastSpell callback
//		param[0] = Caster ID
//		param[1] = Victim ID
//		param[2] = ID of skill used for the search
//		param[3] = ID of target team
//		param[4] = Flags used by PLAYER_CastSpell
//------------------------------------
public _SPELL_Immolate( const param[] )
{
	new iCaster = param[0]
	new iTarget = param[1]

	if( !PLAYER_CheckMagicHit( iCaster, iTarget ) )
	{
		client_print( iCaster, print_chat, "Your Immolate was resisted by %s.", PlayerInfo[iTarget][PI_PlayerName] )
		client_print( iTarget, print_chat, "You resisted %s's Immolate.", PlayerInfo[iCaster][PI_PlayerName] )
		client_cmd( iCaster, "spk %s", g_szSounds[SOUND_DISPELL] )
		return
	}
	
	PlayerInfo[iTarget][PI_IsBurning] = true
	
	// Emit sound and create the fire exploding effect on the player
	emit_sound( iCaster, CHAN_STATIC, g_szSounds[SOUND_IMMOLATE], 0.5, ATTN_NORM, 0, PITCH_NORM )

	new vTargetOrigin[3]
	get_user_origin( iTarget, vTargetOrigin )

	Create_TE_EXPLOSION( vTargetOrigin, vTargetOrigin, g_spr_fireball, 20, 24, 4 )
	Create_TE_EXPLOSION( vTargetOrigin, vTargetOrigin, g_spr_xfire, 30, 24, 4 )
	Create_ScreenShake( iTarget, (10<<12), (2<<12), (5<<12) )

	EFFECT_ScreenFade( iTarget, 0.25, 0.25, COLOR_RGBA(255, 108, 0, 160) )

	PLAYER_MagicDamage( iTarget, iCaster, IMMOLATE_DAMAGE, CSW_IMMOLATE, DMG_BURN )

	new parm_DoT[3]
	parm_DoT[0] = iCaster
	parm_DoT[1] = iTarget
	parm_DoT[2] = IMMOLATE_DOT

	// Start the ultimate DoT
	set_task( 1.0, "_SPELL_Immolate_DoT", TASK_ALIVE_EFFECT + iTarget, parm_DoT, 3 )
	set_task( 0.5, "_SPELL_Immolate_Burn", TASK_ALIVE_EFFECT + iTarget, parm_DoT, 2 )
}


//------------------------------------
// _SPELL_Immolate_DoT
//
//------------------------------------
public _SPELL_Immolate_DoT( parm_DoT[3] )
{
	new iCaster = parm_DoT[0]
	new iTarget = parm_DoT[1]
	new iCounter = parm_DoT[2]

	// Stop DoT if the max number of ticks is reached
	if( --iCounter < 0 || !is_user_alive(iTarget) )
	{
		PlayerInfo[iTarget][PI_IsBurning] = false
		return
	}

	new vTargetOrigin[3]
	get_user_origin( iTarget, vTargetOrigin )
	Create_TE_EXPLOSION( vTargetOrigin, vTargetOrigin, g_spr_xfire, 30, 24, 4 )

	// Emit sound and show the burning effect on the player
	emit_sound( iTarget, CHAN_STATIC, g_szSounds[SOUND_IMMOLATE_BURNING], 0.5, ATTN_NORM, 0, PITCH_NORM )

	EFFECT_ScreenFade( iTarget, 0.25, 0.25, COLOR_RGBA(255, 108, 0, 160) )
	
	// Do the DoT damage
	PLAYER_MagicDamage( iTarget, iCaster, IMMOLATE_DOT_DAMAGE, CSW_IMMOLATE, DMG_BURN )

	parm_DoT[2] = iCounter
	set_task( 1.0, "_SPELL_Immolate_DoT", TASK_ALIVE_EFFECT + iTarget, parm_DoT, 3 )
}


//------------------------------------
// _SPELL_Immolate_Burn
//
//------------------------------------
public _SPELL_Immolate_Burn( parm_DoT[] )
{
	new iTarget = parm_DoT[1]

	if( !PlayerInfo[iTarget][PI_IsBurning] || !is_user_alive(iTarget) )
		return

	new vTargetOrigin[3]
	get_user_origin( iTarget, vTargetOrigin )

	Create_TE_SPRITE( vTargetOrigin, g_spr_explode1, 3, 200 )

	set_task( 0.5, "_SPELL_Immolate_Burn", TASK_ALIVE_EFFECT + iTarget, parm_DoT, 2 )
}



//------------------------------------
// _SPELL_Immolate_Sound
//
//------------------------------------
public _SPELL_Immolate_Sound( parm_DoT[] )
{
	new iTarget = parm_DoT[1]

	if( !PlayerInfo[iTarget][PI_IsBurning] )
		return

}
